package com.example.artemis.events;

/**
 * 消息处理失败事件
 * 当消息处理失败时触发此事件
 */
public class MessageFailedEvent extends MessageEvent {

    private final String consumerId;
    private final long processingTime;
    private final int deliveryAttempt;
    private final String errorMessage;
    private final FailureType failureType;
    private final boolean willRetry;

    public MessageFailedEvent(String messageId, String queueName, String consumerId,
                            long processingTime, int deliveryAttempt,
                            String errorMessage, FailureType failureType, boolean willRetry) {
        super(messageId, queueName);
        this.consumerId = consumerId;
        this.processingTime = processingTime;
        this.deliveryAttempt = deliveryAttempt;
        this.errorMessage = errorMessage;
        this.failureType = failureType;
        this.willRetry = willRetry;
    }

    /**
     * 获取消费者ID
     */
    public String getConsumerId() {
        return consumerId;
    }

    /**
     * 获取消息处理耗时（毫秒）
     */
    public long getProcessingTime() {
        return processingTime;
    }

    /**
     * 获取消息投递尝试次数
     */
    public int getDeliveryAttempt() {
        return deliveryAttempt;
    }

    /**
     * 获取错误信息
     */
    public String getErrorMessage() {
        return errorMessage;
    }

    /**
     * 获取失败类型
     */
    public FailureType getFailureType() {
        return failureType;
    }

    /**
     * 是否会重试
     */
    public boolean isWillRetry() {
        return willRetry;
    }

    @Override
    public String getEventType() {
        return "MESSAGE_FAILED";
    }

    @Override
    public String toString() {
        return String.format("MessageFailedEvent{messageId='%s', queueName='%s', consumerId='%s', " +
                "processingTime=%dms, deliveryAttempt=%d, errorMessage='%s', " +
                "failureType=%s, willRetry=%s, timestamp=%d}",
                getMessageId(), getQueueName(), consumerId, processingTime,
                deliveryAttempt, errorMessage, failureType, willRetry, getTimestamp());
    }

    /**
     * 失败类型枚举
     */
    public enum FailureType {
        /**
         * 运行时异常
         */
        RUNTIME_EXCEPTION,

        /**
         * JMS异常
         */
        JMS_EXCEPTION,

        /**
         * 处理超时
         */
        TIMEOUT,

        /**
         * 业务逻辑失败
         */
        BUSINESS_FAILURE,

        /**
         * 其他未知错误
         */
        UNKNOWN
    }
}